package org.mybatis.generator.ext.plugins;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.Interface;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import org.mybatis.generator.internal.DefaultShellCallback;

public class MvcPlugin extends PluginAdapter {

	private String servicePackage;
	public static String excludeProperty="isDele,updateBy,updateDate,remark,id";

	@Override
	public boolean validate(List<String> warnings) {
		return true;
	}
	@Override
	public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
		try {
			topLevelClass.addJavaDocLine("/**");
			if(StringUtils.isNotBlank(introspectedTable.getTableConfiguration().getAlias()) && StringUtils.isNotEmpty(introspectedTable.getTableConfiguration().getAlias()) ){
				topLevelClass.addJavaDocLine("* "+introspectedTable.getTableConfiguration().getAlias());
			}
			topLevelClass.addJavaDocLine("* 表名:"+introspectedTable.getTableConfiguration().getTableName());
			topLevelClass.addJavaDocLine("**/");
			makeService(topLevelClass, introspectedTable);
			makeController(topLevelClass, introspectedTable);
			makeListView(topLevelClass, introspectedTable);
			makeEditView(topLevelClass, introspectedTable);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return super.modelBaseRecordClassGenerated(topLevelClass, introspectedTable);
	}
	
	
	@Override
	public boolean clientGenerated(Interface interfaze, TopLevelClass topLevelClass,
			IntrospectedTable introspectedTable) {
		// TODO Auto-generated method stub
		return super.clientGenerated(interfaze, topLevelClass, introspectedTable);
	} 
	
	 /**
	  * Service
	  * @param topLevelClass
	  * @param introspectedTable
	  * @throws Exception
	  */
	 protected void makeService(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) throws Exception {
		 //模板
		 File tpl=getTpl("service");
		 //当前实体类名
		 String selfDomainName=introspectedTable.getFullyQualifiedTable().getDomainObjectName();
		 //目标项目绝对路径
		 String projectPath=super.context.getJavaClientGeneratorConfiguration().getTargetProject();
		 //实体类包名
		 String modelPackage=super.context.getJavaModelGeneratorConfiguration().getTargetPackage();
		 //dao包名
		 String mapperPackage=super.context.getJavaClientGeneratorConfiguration().getTargetPackage();
		 //Dao全类名
		 String mapperFullName=mapperPackage+"."+selfDomainName+"Mapper";
		 String mapperName=selfDomainName+"Mapper";
		 String mapperName2=selfDomainName.substring(0,1).toLowerCase()+selfDomainName.substring(1)+"Mapper";
		 //实体全类名
		 String modelFullName=modelPackage+"."+selfDomainName;
		 String modelName2=selfDomainName.substring(0,1).toLowerCase()+selfDomainName.substring(1)+"Model";
		 servicePackage = properties.getProperty("servicePackage","service");
		 String serviceOutPutfolder=new DefaultShellCallback(false).getDirectory(projectPath, File.separator+servicePackage).getAbsolutePath();
		 File outpuFile=new File(serviceOutPutfolder+File.separator+selfDomainName+"Service.java");
		 Map<String, String> root=new HashMap<String, String>();
		 root.put("#MapperFullName#", mapperFullName);
		 root.put("#MapperName#", mapperName);
		 root.put("#mapperName#", mapperName2);
		 root.put("#ModelFullName#", modelFullName);
		 root.put("#ModelName#", selfDomainName);
		 root.put("#modelName#", modelName2);
		 root.put("#servicePackage#", servicePackage);
		 if(!outpuFile.exists()){
			 process(tpl, root, outpuFile);
		 }
	 }
	 /**
	  * 控制器
	  * @param topLevelClass
	  * @param introspectedTable
	  * @throws Exception
	  */
	 protected void makeController(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) throws Exception {
		 //模板
		 File tpl=getTpl("controller");
		 //当前实体类名
		 String selfDomainName=introspectedTable.getFullyQualifiedTable().getDomainObjectName();
		 //目标项目绝对路径
		 String projectPath=super.context.getJavaClientGeneratorConfiguration().getTargetProject();
		 //实体类包名
		 String modelPackage=super.context.getJavaModelGeneratorConfiguration().getTargetPackage();
		 //Service
		 String servicePackage=properties.getProperty("servicePackage","service");
		 String serviceFullName=servicePackage+"."+selfDomainName+"Service";
		 String serviceName=selfDomainName+"Service";
		 String serviceName2=selfDomainName.substring(0,1).toLowerCase()+selfDomainName.substring(1)+"Service";
		 //实体全类名
		 String modelFullName=modelPackage+"."+selfDomainName;
		 String modelName2=selfDomainName.substring(0,1).toLowerCase()+selfDomainName.substring(1)+"Model";
		 String controllerPackage=properties.getProperty("controllerPackage","controller");
		 String controllerOutPutfolder=new DefaultShellCallback(false).getDirectory(projectPath, File.separator+controllerPackage).getAbsolutePath();
		 File outpuFile=new File(controllerOutPutfolder+File.separator+selfDomainName+"Controller.java");
		 Map<String, String> root=new HashMap<String, String>();
		 root.put("#modelName#", modelName2);
		 root.put("#ServiceFullName#", serviceFullName);
		 root.put("#controllerPackage#", controllerPackage);
		 root.put("#ServiceName#", serviceName);
		 root.put("#serviceName#", serviceName2);
		 root.put("#ModelFullName#", modelFullName);
		 root.put("#ModelName#", selfDomainName);
		 String[] packageArray=servicePackage.split("\\.");
		 root.put("#url#", packageArray[packageArray.length-2]+"/"+selfDomainName.toLowerCase());
		 if(!outpuFile.exists()){
			 process(tpl, root, outpuFile);
		 }
		 
	 }
	 
	 
	 protected void makeListView(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) throws Exception {
		 if (null==properties.getProperty("viewFolder")) {
			return ;
		 }
		 //模板
		 File tpl=getTpl("list");
		 List<IntrospectedColumn> columnList=introspectedTable.getBaseColumns();
		 StringBuilder columns=new StringBuilder();
		 for (IntrospectedColumn introspectedColumn : columnList) {
			 if(excludeProperty.indexOf(introspectedColumn.getJavaProperty())!=-1){
				 continue;
			 }
			 columns.append("\t\t\t\t{width:'").append(Integer.parseInt(100/columnList.size()+"")).append("%',");
			 columns.append("field:'").append(introspectedColumn.getJavaProperty()).append("',");
			 columns.append("title:'").append(introspectedColumn.getRemarks()).append("',");
			 columns.append("align:'center'");
			 columns.append("},");
			 columns.append("\n");
		 }
		 String selfDomainName=introspectedTable.getFullyQualifiedTable().getDomainObjectName();
		 String modelName2=selfDomainName.substring(0,1).toLowerCase()+selfDomainName.substring(1)+"Model";
		 Map<String, String> root=new HashMap<String, String>();
		 root.put("#modelName#", modelName2);
		 String[] packageArray=servicePackage.split("\\.");
		 root.put("#url#", packageArray[packageArray.length-2]+"/"+selfDomainName.toLowerCase());
		 root.put("#columns#", columns.toString().trim());
		 String viewOutPutfolder=properties.getProperty("viewFolder")+File.separator+selfDomainName.toLowerCase();
		 File outpuFile=new File(viewOutPutfolder+File.separator+"list.jsp");
		 process(tpl, root,outpuFile );
	 }
	 
	 protected void makeEditView(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) throws Exception {
		 if (null==properties.getProperty("viewFolder")) {
				return ;
		 }
		 File tpl=getTpl("edit");
		 List<IntrospectedColumn> columnList=introspectedTable.getBaseColumns();
		 StringBuilder trs=new StringBuilder();
		 for (int i = 0; i < columnList.size(); i++) {
			 IntrospectedColumn introspectedColumn =columnList.get(i);
			 if(i%2==0){
				 trs.append("<tr>\n\t\t\t\t");
			 }			
			 trs.append("<th>").append(introspectedColumn.getRemarks()).append("</th>");
			 trs.append("\n\t\t\t\t");
			 trs.append("<td>\n\t\t\t\t\t\t<input name=\"").append(introspectedColumn.getJavaProperty()).append("\"");
			 trs.append("class=\""+getInputClass(introspectedColumn.getFullyQualifiedJavaType().getShortName())+"\" "+isRequired(introspectedColumn)+" style=\"width:100%\"");
			 trs.append("value=\"\\${object.").append(introspectedColumn.getJavaProperty()).append("\\}\"");
			 trs.append("/>\n\t\t\t\t</td>");
			 if((i+1)%2==0||i==columnList.size()-1){
				 trs.append("\n");
				 trs.append("\t\t\t\t");
				 trs.append("</tr>");
			 }
			 trs.append("\n\t\t\t\t");
		 }
		 String selfDomainName=introspectedTable.getFullyQualifiedTable().getDomainObjectName();
		 String modelName2=selfDomainName.substring(0,1).toLowerCase()+selfDomainName.substring(1)+"Model";
		 Map<String, String> root=new HashMap<String, String>();
		 root.put("#modelName#", modelName2);
		 root.put("#trs#", trs.toString().trim());
		 String viewOutPutfolder=properties.getProperty("viewFolder")+File.separator+selfDomainName.toLowerCase();
		 File outpuFile=new File(viewOutPutfolder+File.separator+"edit.jsp");
		 process(tpl, root,outpuFile );
	 }
	 
	 	 
	 
	 private String isRequired(IntrospectedColumn introspectedColumn) {
		 if(!introspectedColumn.isNullable()){
			 return "required=\"true\"";
		 }
		return "";
	}
	private String getInputClass(String type) {
		return type.equals("String")?"easyui-textbox":type.equals("Date")?"easyui-datetimebox":"easyui-numberbox";
	}
	private boolean process(File tpl,Map<String, String> root,File opFile){
		 try {
			String tplContent=FileUtils.readFileToString(tpl);
			 for (String key : root.keySet()) {
				 tplContent=tplContent.replaceAll(key, root.get(key));
			 }
			 
			 if(!opFile.getParentFile().exists()){
				 opFile.getParentFile().mkdirs();
			 }
			 if (opFile.exists()) {
				 opFile.delete();
				 opFile.createNewFile();
			 }else{
				 opFile.createNewFile();
			 }
			 FileUtils.writeStringToFile(opFile, tplContent);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		 return true;
	}
	 
	private File getTpl(String name) throws FileNotFoundException {
		File file =new File(properties.getProperty("tplFolder")+File.separator+name+".txt");
		if (!file.exists()) {
			throw new FileNotFoundException("没有找到模板-->"+file.getAbsolutePath());
		}
		return file;
	}
	
}
